﻿using System;
using System.Runtime.InteropServices;

namespace G722
{
    public class g722_encoder
    {
        //IntPtr encoder;
        //public fixed int encoder[100];
        public int[] encoder;
    }

    public class g722
    {
        private const string DLL_NAME = "g722.dll";

        [DllImport(DLL_NAME, EntryPoint = "g722_reset_encoder", CallingConvention = CallingConvention.Cdecl)]
        private static extern int _g722_reset_encoder(IntPtr encoder);

        [DllImport(DLL_NAME, EntryPoint = "g722_encode", CallingConvention = CallingConvention.Cdecl)]
        private static extern int _g722_encode(IntPtr incode, IntPtr code, int read1, IntPtr encoder);

        [DllImport(DLL_NAME, EntryPoint = "g722_reset_decoder", CallingConvention = CallingConvention.Cdecl)]
        private static extern int _g722_reset_decoder(IntPtr decoder);

        [DllImport(DLL_NAME, EntryPoint = "g722_decode", CallingConvention = CallingConvention.Cdecl)]
        private static extern int _g722_decode(IntPtr code, IntPtr outcode, int read1, IntPtr decoder);

        public static void g722_reset_encoder(ref g722_encoder enc)
        {
            enc.encoder = new int[100];
            //Array.Clear(enc.encoder, 0, 100);
            //GCHandle gc = GCHandle.Alloc(enc.encoder);
        }

        public static byte[] g722_encode(short[] incode, ref g722_encoder enc)
        {
            //固定encoder的结构地址，避免被移动
            GCHandle gc_enc = GCHandle.Alloc(enc.encoder, GCHandleType.Pinned);
            IntPtr penc = gc_enc.AddrOfPinnedObject();// GCHandle.ToIntPtr(gc_enc);

            GCHandle gc_incode = GCHandle.Alloc(incode, GCHandleType.Pinned);
            IntPtr pincode = gc_incode.AddrOfPinnedObject();// GCHandle.ToIntPtr(gc_incode);

            //IntPtr pcode = Marshal.AllocHGlobal(incode.Length);

            byte[] code = new byte[incode.Length/2];
            GCHandle gc_code = GCHandle.Alloc(code, GCHandleType.Pinned);
            IntPtr pcode = gc_code.AddrOfPinnedObject();// GCHandle.ToIntPtr(gc_code);

            int len = _g722_encode(pincode, pcode, incode.Length, penc);

            gc_incode.Free();
            gc_enc.Free();
            gc_code.Free();

            return code;
        }
    }
}

